package com.zdp.filesync.rsync.service.impl;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
import com.zdp.filesync.monitor.config.FileMonitorConfig;
import com.zdp.filesync.monitor.config.FileMonitorInfo;
import com.zdp.filesync.rsync.handle.RsyncHandle;
import com.zdp.filesync.rsync.service.RsyncConfigRefresh;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class RsyncConfigRefreshImpl implements RsyncConfigRefresh {

    @Autowired
    private RsyncHandle rsyncHandle;
    @Autowired
    FileMonitorConfig fileMonitorConfig;
    @Override
    public void refreshRsyncConfig(FileMonitorConfig newFileMonitorRsyncConfig) {
        Map<String,FileMonitorInfo> oldConfig = getFileMonitorConfigMap(fileMonitorConfig);
        Map<String,FileMonitorInfo> newConfig = getFileMonitorConfigMap(newFileMonitorRsyncConfig);
        // 筛选得到需要 删除的 模块配置 (旧的配置不存在在新的配置中 + commentName变化）
        List<FileMonitorInfo> delFileMonitorInfo = oldConfig.values().stream().filter(oldInfo -> {
            FileMonitorInfo fileMonitorInfo = newConfig.get(oldInfo.getPath());
            return Objects.isNull(fileMonitorInfo)
                    || !StringUtils.equals(oldInfo.getCommentName(),fileMonitorInfo.getCommentName());
        }).collect(Collectors.toList());
        // 得到需要新增的模块配置 （新的配置不存在在旧的配置中）
        List<FileMonitorInfo> addFileMonitorInfo = newConfig.values().stream()
                .filter(newInfo -> !oldConfig.containsKey(newInfo.getPath()))
                .collect(Collectors.toList());
        rsyncHandle.delModelConfig(delFileMonitorInfo);
        rsyncHandle.addModelConfig(addFileMonitorInfo);
        rsyncHandle.restart();
    }

    private Map<String,FileMonitorInfo> getFileMonitorConfigMap(FileMonitorConfig fileMonitorConfig){
        List<FileMonitorInfo> fileMonitorInfos = Optional.ofNullable(fileMonitorConfig)
                .map(FileMonitorConfig::getFileMonitorInfos)
                .orElse(Lists.newArrayList());
        if(CollectionUtils.isEmpty(fileMonitorInfos)){
            return Maps.newHashMap();
        }else{
            return fileMonitorInfos.stream()
                    .collect(Collectors.toMap(FileMonitorInfo::getPath, Function.identity(),(val1,val2)-> val1));
        }
    }
}
